package com.aikon.wht.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadCommunication {

	private final Lock lockA = new ReentrantLock();

	private Lock lockB = new ReentrantLock();

	private char turn = 'A';

	private int i;

	private int a = 100;

	private final Condition conditionA = lockA.newCondition();

	private final Condition conditionB = lockA.newCondition();

	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		ThreadCommunication tc = new ThreadCommunication();
		executor.execute(tc.new RunnableA());
		executor.execute(tc.new RunnableB());
		executor.shutdown();
	}

	public class RunnableA implements Runnable {

		public void run() {
			lockA.lock();
			try {
				while (turn == 'A' && i < 50) {
					System.out.println(i);
					i++;
					turn = 'B';
					try {
						conditionB.signal();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}

			} finally {
				System.out.println("signal B");
				conditionB.signal();
				lockA.unlock();
			}
		}

	}

	public class RunnableB implements Runnable {

		public void run() {
			lockA.lock();
			try {
				conditionB.await();
				System.out.println("B start");
				while ('B' == turn && i < 200) {
					
					System.out.println("Await B");
					System.out.println("xxx");
					System.out.println(a);
					a++;
					turn = 'A';
					conditionB.await();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				conditionA.signal();
				lockA.unlock();
			}

		}

	}

}
